package com.bjkcst.baselib.utils;


import com.google.common.util.concurrent.ThreadFactoryBuilder;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * author: glc.
 * Date: 2022/5/13  15:32
 * Description:
 */
public class KcstThreadPool {

    /** 核心线程数*/
    private int mCorePoolSize = 3;
    /** 最大线程数*/
    private int mMaxImumPoolSize = 10;
    /** 超时时间 30秒*/
    private long mKeepAliveTime = 30;


    private ThreadPoolExecutor mThreadPoolExecutor;
    private volatile static KcstThreadPool mInstance;

    public static KcstThreadPool getInstance(){
        if (mInstance == null){
            synchronized (KcstThreadPool.class){
                if (mInstance == null){
                    mInstance = new KcstThreadPool();
                }
            }
        }
        return mInstance;
    }


    private KcstThreadPool(){
        mThreadPoolExecutor = new ThreadPoolExecutor(mCorePoolSize, mMaxImumPoolSize, mKeepAliveTime,
                TimeUnit.SECONDS, new LinkedBlockingDeque<>(),
                new ThreadFactoryBuilder().setNameFormat("thread-pol-kcst-%d").build());
    }

    public void singleExecute(Runnable runnable){
        mThreadPoolExecutor.execute(runnable);
    }

    /**
     * 单独task返回结果
     *
     * @param task
     * @param <V>
     */
    public <V> V submit(CallableTemplate<V> task) throws InterruptedException,
            ExecutionException {
        Future<V> result = mThreadPoolExecutor.submit(task);

        return result.get();
    }

    /**
     * 提交多任务并发返回结果
     *
     * @param tasks
     * @param <V>
     */
    public <V> List<V> invokeAll(List<? extends CallableTemplate<V>> tasks)
            throws InterruptedException, ExecutionException {

        List<Future<V>> tasksResult = mThreadPoolExecutor.invokeAll(tasks);
        List<V> resultList = new ArrayList<>();

        for (Future<V> future : tasksResult) {
            resultList.add(future.get());
        }

        return resultList;
    }

    /**
     * 打断
     */
    public void breakTask() {
        if (mThreadPoolExecutor != null && !mThreadPoolExecutor.isShutdown()) {
            mThreadPoolExecutor.shutdown();
        }
    }

    /**
     * 停止
     */
    public void stopSelf() {
        if (mThreadPoolExecutor != null && !mThreadPoolExecutor.isShutdown()) {
            mThreadPoolExecutor.shutdownNow();
        }
    }


    public boolean isRunning() {
        if (mThreadPoolExecutor.isShutdown()) {
            return false;
        } else if (mThreadPoolExecutor.isTerminated()) {
            return false;
        }
        return true;
    }
}
